Análise de novos fatores de boosting¶

Nesta análise vamos partir dos conhecimentos adquiridos na análise de podas do AQE, onde descobrimos que utilizar a ordem do fator de boosting com até cinco termos é o método de poda mais razoável para o caso geral, o qual obteve NDCG@24 de 76,58%. Nesse método, foi fixado o fator de boosting de 0.100 para todos os termos, independente da base utilizada. Agora, vamos experimentar com diferentes fatores de boosting para diferentes bases de dados.

Na análise das bases de dados, identificamos também as bases de dados mais relevantes para o problema. Agora vamos utilizar as três bases de dados mais relevantes, inicialmente com os pesos estáticos e similares aos identificados durante a análise anterior, os quais estão descritos abaixo:

  1. 06_Termos_TabelaPocosANP2019: 0.1
  2. 13_Lista_MWE: 0.08
  3. 02_Tesauro_comTraducoesRegis: 0.1

Carregando libs¶

In [1]:
from itertools import product
from pathlib import Path
import json
import yaml
import numpy as np
import pandas as pd
import plotly.express as px

from utils.utils import get_expanded_queries, make_elasticsearch_new_aqe_queries,\
    create_new_expanded_queries, create_new_aqe_validation_dataset, create_new_aqe_metrics,\
    expanded_with_aqe_boost_order, make_elasticsearch_new_queries, adjust_new_expanded_queries,\
    create_new_validation_dataset, create_new_metrics

Carregando as configurações e bases dados¶

In [2]:
with open("../conf/config.yaml", "r") as yamlfile:
    cfg = yaml.safe_load(yamlfile)
In [3]:
with open("../../dados/regis/regis_queries.json", 'r') as regis_file:
    regis_queries = json.load(regis_file)
In [4]:
regis_queries = get_expanded_queries(regis_queries)
regis_queries[:2]
Out[4]:
[{'title': 'História da geoquímica na Petrobras',
  'query_id': 'Q1',
  'expanded_query': '((História da geoquímica na Petrobras) OR ( (historia^1.000 OR história^0.890 OR history^0.571 OR "histórico do campo"^0.525 OR review^0.159 OR revisão^0.164 OR "histórico de caso"^0.225) OR (geoquimica^1.000 OR geoquímica^0.890 OR geoquímicas^0.691 OR geoquímico^0.672 OR geoquimicos^0.736 OR geoquimicas^0.691 OR geoquimico^0.672 OR geochemistry^0.601 OR "geochemical anomaly"^0.225 OR "geochemical interpretation"^0.225 OR "composição dos sedimentos"^0.225 OR "sediment composition"^0.225 OR geology^0.195 OR geologia^0.253 OR petrochemistry^0.153 OR petroquímica^0.184 OR "geochemical cycle"^0.225 OR petrografia^0.255 OR petrography^0.191 OR "análise de rochas"^0.225 OR "rock analysis"^0.225 OR "composição das rochas"^0.225 OR "rock composition"^0.225 OR transect^0.150 OR "geochemical map"^0.225 OR "geochemical exploration"^0.225 OR "geochemical logging"^0.225 OR geophysics^0.179 OR geofísica^0.256 OR "geochemical data"^0.225) OR petrobras^1.000 ))'},
 {'title': 'Lógica fuzzy aplicada  à industria do petróleo',
  'query_id': 'Q2',
  'expanded_query': '((Lógica fuzzy aplicada à industria do petróleo) OR ( ("logica fuzzy"^1.000 OR "lógica fuzzy"^0.667 OR "lógica difusa"^0.667 OR "logica nebulosa"^0.667 OR "logica difusa"^0.667 OR "fuzzy logic"^0.667) OR ("industria do petroleo"^1.000 OR "indústria do petróleo"^0.667 OR "industria de petroleo"^0.667 OR "petroleum industry"^0.667) OR (logica^1.000 OR lógica^0.890 OR lógico^0.744) OR fuzzy^1.000 OR (aplicada^1.000 OR aplicado^0.795 OR aplicados^0.756) OR (industria^1.000 OR indústria^0.890 OR industry^0.576) OR (petroleo^1.000 OR petróleo^0.890 OR petróleos^0.705 OR petroleos^0.705 OR petroleum^0.632 OR "gasolina natural"^0.525 OR "natural gas"^0.350 OR "gás natural"^0.423 OR "commingled production"^0.525 OR "produção misturada"^0.525 OR "óleo cru"^0.525 OR "crude oil"^0.353 OR "hydrocarbon potential"^0.225 OR "potencial de hidrocarbonetos"^0.225 OR "fluido do reservatório"^0.225 OR "reservoir fluid"^0.225 OR "raw material"^0.225 OR "matéria prima"^0.224 OR "razão de hidrocarbonetos"^0.225 OR "hydrocarbon ratio"^0.225 OR "fossil fuel"^0.150 OR "combustível fóssil"^0.225) ))'}]
In [5]:
ground_truth = pd.read_csv(
    "../../dados/regis/regis_ground_truth.csv"
).rename(
    columns={"relevance": "relevance_ground_truth"}
)
ground_truth.head()
Out[5]:
query_id document_id relevance_ground_truth
0 Q1 BR-BG.03944 1
1 Q1 BR-BG.03925 1
2 Q1 BR-TU.23384 0
3 Q1 BR-TU.12209 0
4 Q1 BR-BG.04089 2
In [6]:
data_path = Path("../../dados/vocabulario_oil_gas")
databases = dict()

with open(data_path.joinpath("01_DicionarioPetroleo_Curado_ComSinonimos.csv"), "r", encoding='unicode_escape') as f:
    databases["01_DicionarioPetroleo_Curado_ComSinonimos"] = f.read().replace(";", "\n").split("\n")
    databases["01_DicionarioPetroleo_Curado_ComSinonimos"] = [e.strip().lower() for e in databases["01_DicionarioPetroleo_Curado_ComSinonimos"]]

with open(data_path.joinpath("02_Tesauro_comTraducoesRegis.csv"), "r", encoding='unicode_escape') as f:
    databases["02_Tesauro_comTraducoesRegis"] = f.read().replace("#", ";").replace("\t", "").replace(";", "\n").split("\n")
    databases["02_Tesauro_comTraducoesRegis"] = [e.strip().lower() for e in databases["02_Tesauro_comTraducoesRegis"] if e != ""]

with open(data_path.joinpath("03_ListaCurada.csv"), "r", encoding='unicode_escape') as f:
    databases["03_ListaCurada"] = f.read().split("\n")
    databases["03_ListaCurada"] = [e.strip().lower() for e in databases["03_ListaCurada"] if e != ""]

with open(data_path.joinpath("05_InstanciasBDIEP_Ativo_Bloco_Campo.csv"), "r", encoding='unicode_escape') as f:
    databases["05_InstanciasBDIEP_Ativo_Bloco_Campo"] = f.read().replace(";", "\n").split("\n")
    databases["05_InstanciasBDIEP_Ativo_Bloco_Campo"] = [e.strip().lower() for e in databases["05_InstanciasBDIEP_Ativo_Bloco_Campo"] if e != ""]

with open(data_path.joinpath("06_Termos_TabelaPocosANP2019.csv"), "r", encoding='unicode_escape') as f:
    databases["06_Termos_TabelaPocosANP2019"] = f.read().replace(";", "\n").split("\n")
    databases["06_Termos_TabelaPocosANP2019"] = [e.strip().lower() for e in databases["06_Termos_TabelaPocosANP2019"] if e != ""]

with open(data_path.joinpath("07_Pocos_TabelaPocosANP2019.csv"), "r", encoding='unicode_escape') as f:
    databases["07_Pocos_TabelaPocosANP2019"] = f.read().replace(";", "\n").split("\n")
    databases["07_Pocos_TabelaPocosANP2019"] = [e.strip().lower() for e in databases["07_Pocos_TabelaPocosANP2019"] if e != ""]

with open(data_path.joinpath("08_Pocos_BDIEP_com2ou3_Siglas.csv"), "r", encoding='utf-8-sig') as f:
    databases["08_Pocos_BDIEP_com2ou3_Siglas"] = f.read().replace(";", "\n").split("\n")
    databases["08_Pocos_BDIEP_com2ou3_Siglas"] = [e.strip().lower() for e in databases["08_Pocos_BDIEP_com2ou3_Siglas"] if e != ""]

with open(data_path.joinpath("09_Glossario_ANP.csv"), "r", encoding='unicode_escape') as f:
    databases["09_Glossario_ANP"] = f.read().replace(";", "\n").split("\n")
    databases["09_Glossario_ANP"] = [e.strip().lower() for e in databases["09_Glossario_ANP"] if e != ""]

with open(data_path.joinpath("10_List_of_abbreviations_curada.csv"), "r", encoding='unicode_escape') as f:
    databases["10_List_of_abbreviations_curada"] = f.read().replace(";", "\n").split("\n")
    databases["10_List_of_abbreviations_curada"] = [e.strip().lower() for e in databases["10_List_of_abbreviations_curada"] if e != ""]

with open(data_path.joinpath("11_Lista_Feita_a_Mao.csv"), "r", encoding='unicode_escape') as f:
    databases["11_Lista_Feita_a_Mao"] = f.read().replace(",", ";").replace(";", "\n").split("\n")
    databases["11_Lista_Feita_a_Mao"] = [e.strip().lower() for e in databases["11_Lista_Feita_a_Mao"] if e != ""]

with open(data_path.joinpath("12_Partex_Acronymis_Oil_Gas.csv"), "r") as f:
    databases["12_Partex_Acronymis_Oil_Gas"] = f.read().replace(";", "\n").split("\n")
    databases["12_Partex_Acronymis_Oil_Gas"] = [e.strip().lower() for e in databases["12_Partex_Acronymis_Oil_Gas"] if e != ""]

with open(data_path.joinpath("13_Lista_MWE.txt"), "r") as f:
    databases["13_Lista_MWE"] = f.read().replace(",", "\n").split("\n")
    databases["13_Lista_MWE"] = [e.strip().lower() for e in databases["13_Lista_MWE"] if e != ""]
In [7]:
databases_factors = {
    "02_Tesauro_comTraducoesRegis": np.arange(0.02, 0.11, 0.02).tolist(),
    "06_Termos_TabelaPocosANP2019": np.arange(0.02, 0.11, 0.02).tolist(),
    "13_Lista_MWE": np.arange(0.02, 0.11, 0.02).tolist(),
}

Criando queries com bases mais relevantes e podas baseadas nos fatores de boosting do AQE¶

Aqui vamos experimentar utilizar as bases mais relevantes, descritas anteriormente em conjunto com uma poda com os cinco termos de maior fator estabelecidos pelo AQE.

In [8]:
all_expanded_queries = list()
for query in regis_queries:
    new_expanded_queries = create_new_expanded_queries(
        query["expanded_query"],
        expansion=expanded_with_aqe_boost_order,
        num_termos=[5]
    )

    for num_termos, new_expanded_query in new_expanded_queries:
        q = query.copy()
        q["expanded_query"] = new_expanded_query
        all_expanded_queries.append(q)

databases_factors_products = [
    dict(zip(databases_factors.keys(), dbf_values)) for
    dbf_values in product(*databases_factors.values())
]
all_adjusted_expanded_queries = list()
for dbf in databases_factors_products:
    dbf_queries = adjust_new_expanded_queries(
        {k: v for k, v in databases.items() if k in databases_factors.keys()},
        all_expanded_queries,
        dbf,
        False
    )
    dbf_queries = [
        dbf_query | {"boost_factor_{}".format(dbf_k): dbf_v for dbf_k, dbf_v in dbf.items()} for
        dbf_query in dbf_queries]
    all_adjusted_expanded_queries.extend(dbf_queries)
all_adjusted_expanded_queries[:2]
Out[8]:
[{'title': 'História da geoquímica na Petrobras',
  'query_id': 'Q1',
  'expanded_query': '((História da geoquímica na Petrobras) OR ((historia^0.000 OR história^0.020 OR history^0.020 OR "histórico do campo"^0.020 OR review^0.020 OR revisão^0.020 OR "histórico de caso"^0.020) OR (geoquimica^0.000 OR geoquímica^0.020 OR geoquímicas^0.000 OR geoquímico^0.000 OR geoquimicos^0.000 OR geoquimicas^0.000 OR geoquimico^0.000 OR geochemistry^0.020 OR "geochemical anomaly"^0.020 OR "geochemical interpretation"^0.020 OR "composição dos sedimentos"^0.020 OR "sediment composition"^0.020 OR geology^0.020 OR geologia^0.020 OR petrochemistry^0.020 OR petroquímica^0.020 OR "geochemical cycle"^0.020 OR petrografia^0.020 OR petrography^0.020 OR "análise de rochas"^0.020 OR "rock analysis"^0.020 OR "composição das rochas"^0.020 OR "rock composition"^0.020 OR transect^0.020 OR "geochemical map"^0.020 OR "geochemical exploration"^0.020 OR "geochemical logging"^0.020 OR geophysics^0.020 OR geofísica^0.020 OR "geochemical data"^0.020) OR petrobras^0.020 ))',
  'boost_factor_02_Tesauro_comTraducoesRegis': 0.02,
  'boost_factor_06_Termos_TabelaPocosANP2019': 0.02,
  'boost_factor_13_Lista_MWE': 0.02},
 {'title': 'Lógica fuzzy aplicada  à industria do petróleo',
  'query_id': 'Q2',
  'expanded_query': '((Lógica fuzzy aplicada à industria do petróleo) OR (("logica fuzzy"^0.000 OR "lógica fuzzy"^0.020 OR "lógica difusa"^0.020 OR "logica nebulosa"^0.000 OR "logica difusa"^0.000 OR "fuzzy logic"^0.020) OR ("industria do petroleo"^0.000 OR "indústria do petróleo"^0.000 OR "industria de petroleo"^0.000 OR "petroleum industry"^0.020) OR (logica^0.000 OR lógica^0.000 OR lógico^0.000) OR fuzzy^0.000 OR (aplicada^0.000 OR aplicado^0.000 OR aplicados^0.000) OR (industria^0.000 OR indústria^0.020 OR industry^0.020) OR (petroleo^0.000 OR petróleo^0.020 OR petróleos^0.000 OR petroleos^0.000 OR petroleum^0.020 OR "gasolina natural"^0.020 OR "natural gas"^0.020 OR "gás natural"^0.020 OR "commingled production"^0.020 OR "produção misturada"^0.020 OR "óleo cru"^0.020 OR "crude oil"^0.020 OR "hydrocarbon potential"^0.020 OR "potencial de hidrocarbonetos"^0.020 OR "fluido do reservatório"^0.020 OR "reservoir fluid"^0.020 OR "raw material"^0.020 OR "matéria prima"^0.020 OR "razão de hidrocarbonetos"^0.020 OR "hydrocarbon ratio"^0.020 OR "fossil fuel"^0.020 OR "combustível fóssil"^0.020) ))',
  'boost_factor_02_Tesauro_comTraducoesRegis': 0.02,
  'boost_factor_06_Termos_TabelaPocosANP2019': 0.02,
  'boost_factor_13_Lista_MWE': 0.02}]

Realizando consultas no Elasticsearch¶

Em posse das queries que utilizam cinco termos vamos criar o dataset de validação, o qual possui informações do ground truth da base de dados REGIS.

In [9]:
ranking_result_df = make_elasticsearch_new_aqe_queries(
    all_adjusted_expanded_queries,
    cfg,
    num_docs=24,
    attrs=[
        'query_id',
        'boost_factor_02_Tesauro_comTraducoesRegis',
        'boost_factor_06_Termos_TabelaPocosANP2019',
        'boost_factor_13_Lista_MWE'
    ]
)
ranking_result_df.head()
Out[9]:
query_id boost_factor_02_Tesauro_comTraducoesRegis boost_factor_06_Termos_TabelaPocosANP2019 boost_factor_13_Lista_MWE document_id relevance_ranking
0 Q1 0.02 0.02 0.02 BR-BG.03964 10.422632
1 Q1 0.02 0.02 0.02 BR-BG.03967 10.235765
2 Q1 0.02 0.02 0.02 BR-BG.04004 10.119093
3 Q1 0.02 0.02 0.02 BR-TU.19978 9.964494
4 Q1 0.02 0.02 0.02 BR-BG.04149 9.742469
In [10]:
boost_cols = [
    "boost_factor_02_Tesauro_comTraducoesRegis",
    "boost_factor_06_Termos_TabelaPocosANP2019",
    "boost_factor_13_Lista_MWE"
]

validation_dataset = create_new_aqe_validation_dataset(ranking_result_df, ground_truth, boost_cols)
validation_dataset.head()
Out[10]:
query_id boost_factor_02_Tesauro_comTraducoesRegis boost_factor_06_Termos_TabelaPocosANP2019 boost_factor_13_Lista_MWE document_id relevance_ranking relevance_ground_truth evaluated
0 Q1 0.02 0.02 0.02 BR-BG.03964 10.422632 2.0 True
1 Q1 0.02 0.02 0.02 BR-BG.03967 10.235765 3.0 True
2 Q1 0.02 0.02 0.02 BR-BG.04004 10.119093 1.0 True
3 Q1 0.02 0.02 0.02 BR-TU.19978 9.964494 0.0 True
4 Q1 0.02 0.02 0.02 BR-BG.04149 9.742469 1.0 True

Análise das consultas no Elasticsearch¶

Agora vamos criar as métricas para cada base de dados e quantidade de termos derivados e visualizar os resultados.

Criando métricas¶

In [11]:
boost_cols=[
    "boost_factor_02_Tesauro_comTraducoesRegis",
    "boost_factor_06_Termos_TabelaPocosANP2019",
    "boost_factor_13_Lista_MWE"
]
metrics_df = create_new_aqe_metrics(validation_dataset, boost_cols=boost_cols)
metrics_df.head()
Out[11]:
query_id boost_factor_02_Tesauro_comTraducoesRegis boost_factor_06_Termos_TabelaPocosANP2019 boost_factor_13_Lista_MWE ndcg@24 ap@24 eval_prop
0 Q1 0.02 0.02 0.02 0.766755 0.355489 0.925926
1 Q1 0.02 0.02 0.04 0.766755 0.355489 0.925926
2 Q1 0.02 0.02 0.06 0.766755 0.355489 0.925926
3 Q1 0.02 0.02 0.08 0.766755 0.355489 0.925926
4 Q1 0.02 0.02 0.10 0.766755 0.355489 0.925926

Avaliando métricas¶

Vamos agora avaliar as métricas. Vamos utilizar as seguintes métricas:

  • ndcg - Normalized Discounted Cumulative Gain
  • map - Mean Average Precision
  • eval_prop - Proporção de documentos avaliados

Vejamos qual a melhor quantidade de termos derivados para cada query:

In [12]:
boost_cols=["boost_factor_02_Tesauro_comTraducoesRegis",
            "boost_factor_06_Termos_TabelaPocosANP2019",
            "boost_factor_13_Lista_MWE"]
    
data_viz = metrics_df.melt(
    id_vars=["query_id", "ndcg@24"], value_vars=boost_cols,
    var_name="database", value_name="boost_factor"
).groupby(
    ["database", "boost_factor"]
).agg(
    ndcg_mean=("ndcg@24", "mean")
).reset_index()


fig = px.line(
    data_viz,
    x="boost_factor",
    y="ndcg_mean",
    color="database",
    markers=True,
    labels={
        "boost_factor": "Fator de boost",
        "ndcg_mean": "NDCG@24 médio",
    }
)
fig.show()

Podemos ver que para o tesauro, o melhor fator de boost é de 0,02, enquanto para a lista MWE e a tabela de poços traz o melhor fator de boost em 0,06.

Vejamos se as combinações com melhores NDCGs@24 médios concordam com esses valores.

In [13]:
metrics_df.groupby(
    boost_cols
).agg(
    ndcg_mean=("ndcg@24", "mean"),
).reset_index(
).rename(
    columns={"ndcg_mean": "ndcg@24 mean"}
).sort_values(
    "ndcg@24 mean", ascending=False
).head(5)
Out[13]:
boost_factor_02_Tesauro_comTraducoesRegis boost_factor_06_Termos_TabelaPocosANP2019 boost_factor_13_Lista_MWE ndcg@24 mean
17 0.02 0.08 0.06 0.777160
19 0.02 0.08 0.10 0.777035
18 0.02 0.08 0.08 0.776854
23 0.02 0.10 0.08 0.776646
12 0.02 0.06 0.06 0.776610

Percebemos que quando usamos os fatores em conjunto, os valores são ligeiramente diferentes, onde a tabela de poços trouxe o melhor fator de boost em 0,08, enquanto os demais permaneceram os mesmos.

O valor de NDCG@24 encontrado anteriormente, utilizando todas as bases de dados, com pesos derivados do AQE e sem podas foi de 0.779687, que é maior que o maior valor encontrado utilizando estes valores.

Vamos agora experimentar com os mesmos fatores utilizados no experimento de análise da base de dados, utilizando o fator de multiplicação ao invés de estático por base, para identificar se a poda de fato traz um ganho.

In [14]:
databases_factors = {
    "01_DicionarioPetroleo_Curado_ComSinonimos": 0.03,
    "02_Tesauro_comTraducoesRegis": 0.1,
    "03_ListaCurada": 0.0,
    "05_InstanciasBDIEP_Ativo_Bloco_Campo": 0.01,
    "06_Termos_TabelaPocosANP2019": 0.1,
    "07_Pocos_TabelaPocosANP2019": 0.0,
    "08_Pocos_BDIEP_com2ou3_Siglas": 0.0,
    "09_Glossario_ANP": 0.33,
    "10_List_of_abbreviations_curada": 0.11,
    "11_Lista_Feita_a_Mao": 0.0,
    "12_Partex_Acronymis_Oil_Gas": 0.12,
    "13_Lista_MWE": 0.08,
}
In [15]:
all_expanded_queries = list()
for query in regis_queries:
    new_expanded_queries = adjust_new_expanded_queries(
        databases, [query], databases_factors, True
    )[0]

    new_expanded_queries = create_new_expanded_queries(
        new_expanded_queries["expanded_query"],
        expansion=expanded_with_aqe_boost_order,
        num_termos=[5],
        factor=None
    )
   
    for i, new_expanded_query in new_expanded_queries:
        q = query.copy()
        q["expanded_query"] = new_expanded_query
        all_expanded_queries.append(q)


all_expanded_queries[:2]
Out[15]:
[{'title': 'História da geoquímica na Petrobras',
  'query_id': 'Q1',
  'expanded_query': '((História da geoquímica na Petrobras) OR ((historia^0.000 OR história^0.000 OR history^0.057 OR "histórico do campo"^0.000 OR review^0.016 OR revisão^0.000 OR "histórico de caso"^0.000) OR (geoquimica^0.000 OR geoquímica^0.000 OR geoquímicas^0.000 OR geoquímico^0.000 OR geoquimicos^0.000 OR geoquimicas^0.000 OR geoquimico^0.000 OR geochemistry^0.060 OR "geochemical anomaly"^0.018 OR "geochemical interpretation"^0.018 OR "composição dos sedimentos"^0.000 OR "sediment composition"^0.018 OR geology^0.000 OR geologia^0.000 OR petrochemistry^0.000 OR petroquímica^0.000 OR "geochemical cycle"^0.000 OR petrografia^0.000 OR petrography^0.019 OR "análise de rochas"^0.000 OR "rock analysis"^0.000 OR "composição das rochas"^0.000 OR "rock composition"^0.000 OR transect^0.000 OR "geochemical map"^0.000 OR "geochemical exploration"^0.000 OR "geochemical logging"^0.000 OR geophysics^0.000 OR geofísica^0.000 OR "geochemical data"^0.000) OR petrobras^0.100 ))'},
 {'title': 'Lógica fuzzy aplicada  à industria do petróleo',
  'query_id': 'Q2',
  'expanded_query': '((Lógica fuzzy aplicada à industria do petróleo) OR (("logica fuzzy"^0.000 OR "lógica fuzzy"^0.067 OR "lógica difusa"^0.067 OR "logica nebulosa"^0.000 OR "logica difusa"^0.000 OR "fuzzy logic"^0.020) OR ("industria do petroleo"^0.000 OR "indústria do petróleo"^0.220 OR "industria de petroleo"^0.000 OR "petroleum industry"^0.020) OR (logica^0.000 OR lógica^0.000 OR lógico^0.000) OR fuzzy^0.000 OR (aplicada^0.000 OR aplicado^0.000 OR aplicados^0.000) OR (industria^0.000 OR indústria^0.000 OR industry^0.058) OR (petroleo^0.000 OR petróleo^0.294 OR petróleos^0.000 OR petroleos^0.000 OR petroleum^0.000 OR "gasolina natural"^0.042 OR "natural gas"^0.000 OR "gás natural"^0.140 OR "commingled production"^0.042 OR "produção misturada"^0.000 OR "óleo cru"^0.000 OR "crude oil"^0.000 OR "hydrocarbon potential"^0.018 OR "potencial de hidrocarbonetos"^0.000 OR "fluido do reservatório"^0.000 OR "reservoir fluid"^0.000 OR "raw material"^0.000 OR "matéria prima"^0.000 OR "razão de hidrocarbonetos"^0.000 OR "hydrocarbon ratio"^0.000 OR "fossil fuel"^0.000 OR "combustível fóssil"^0.000) ))'}]
In [16]:
ranking_result_df = make_elasticsearch_new_queries(all_expanded_queries, cfg, 24)
ranking_result_df.head()
Out[16]:
query_id document_id relevance_ranking
0 Q1 BR-BG.03964 10.403919
1 Q1 BR-BG.03967 10.235914
2 Q1 BR-BG.04004 10.167183
3 Q1 BR-BG.03925 9.871521
4 Q1 BR-TU.20287 9.773394
In [17]:
validation_dataset = create_new_validation_dataset(ranking_result_df, ground_truth)
validation_dataset.head()
Out[17]:
query_id document_id relevance_ranking relevance_ground_truth evaluated
0 Q1 BR-BG.03964 10.403919 2.0 True
1 Q1 BR-BG.03967 10.235914 3.0 True
2 Q1 BR-BG.04004 10.167183 1.0 True
3 Q1 BR-BG.03925 9.871521 1.0 True
4 Q1 BR-TU.20287 9.773394 0.0 True
In [18]:
metrics_df = create_new_metrics(validation_dataset)
metrics_df.head()
Out[18]:
query_id ndcg@24 ap@24 eval_prop
0 Q1 0.760593 0.357143 0.910714
1 Q10 0.948373 0.819179 1.000000
2 Q11 0.693449 0.450000 1.000000
3 Q12 0.783449 0.462137 0.974359
4 Q13 0.954916 0.855791 0.962963
In [19]:
metrics_df["ndcg@24"].mean()
Out[19]:
0.7833242127955737

Podemos ver que a métrica atingida por esse método é o que trouxe melhores resultados até então.

Conclusão¶

Nesta análise duas abordagens foram testadas: experimentar diferentes pesos com as três bases mais relevantes encontradas na análise das base de dados e utilizar os fatores de multiplicação de boosting, também encontrado na análise das bases de dados, ambos seguidos de uma poda com 5 termos.

Apesar de atingir uma métrica de ranking superior ao Elasticsearch puro, a primeira abordagem resultou em uma métrica inferior às encontradas em análises anteriores, com um NDCG@24 de 77,72%, logo foi descartada. Já a segunda abordagem trouxe os melhores valores encontrados até então, atingingo um NDCG@24 de 78,33%. A nível comparativo, o Elasticsearch puro resulta em um NDCG@24 de 76,58%, utilizar apenas os fatores de multiplicação dos boosts resulta em um NDCG@24 de 77,97%, utilizar o mecanismo de poda com cinco termos derivados resulta em um NDCG@24 de 76,58%, enquanto utilizar os fatores de multiplicação dos boosts em conjunto com o mecanismo de poda com cinco termos derivados (segunda abordagem) resulta em um NDCG@24 de 78,33%. Os fatores de multiplicação da segunda abordagem, os quais multiplicam os fatores de boost retornados pelo AQE, estão descritos a seguir:

  • 01_DicionarioPetroleo_Curado_ComSinonimos: 0.03
  • 02_Tesauro_comTraducoesRegis: 0.1
  • 03_ListaCurada: 0.0
  • 05_InstanciasBDIEP_Ativo_Bloco_Campo: 0.01
  • 06_Termos_TabelaPocosANP2019: 0.1
  • 07_Pocos_TabelaPocosANP2019: 0.0
  • 08_Pocos_BDIEP_com2ou3_Siglas: 0.0
  • 09_Glossario_ANP: 0.33
  • 10_List_of_abbreviations_curada: 0.11
  • 11_Lista_Feita_a_Mao: 0.0
  • 12_Partex_Acronymis_Oil_Gas: 0.12
  • 13_Lista_MWE: 0.08

Vale lembrar que a poda com cinco termos foi realizada posteriormente à multiplicação dos fatores de boost pelos pesos descritos acima, utilizando os cinco termos com maior boost para cada termo derivado.